package com.ushine.web.communication.tcp;

import com.alibaba.fastjson.JSON;
import com.ushine.web.communication.des.server.model.NetworkDO;
import com.ushine.web.communication.des.server.service.NetWorkService;
import com.ushine.web.component.http.HttpResponseVO;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketCloseStatus;
import io.netty.handler.codec.http.websocketx.WebSocketFrame;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;

/**
 * @Author: yls
 * @Date 2022/5/9 9:37
 * @Description: 通过IOC管理 Netty 的Handler
 * @Version 1.0
 **/
@Slf4j
@Component
@ChannelHandler.Sharable
public class NettyMessageHandler extends SimpleChannelInboundHandler<WebSocketFrame> {

    private static final String MODEL = "netty-websocket通信处理器=》";

    @Resource
    NetWorkService netWorkService;

    @Override
    protected void channelRead0(ChannelHandlerContext context, WebSocketFrame msg) throws IllegalBlockSizeException, NoSuchAlgorithmException, IOException, BadPaddingException, NoSuchPaddingException, InvalidKeyException, InvalidKeySpecException {
        if (msg instanceof TextWebSocketFrame) {
            // 获取加解密对象
            NetworkDO networkDO = NetWorkService.NET_WORK_DO;
            TextWebSocketFrame textWebSocketFrame = (TextWebSocketFrame) msg;
            String text = textWebSocketFrame.text();
            // 解密
            log.info("{}接收到客户端的消息：{}", MODEL, text);
            HttpResponseVO<Object> decRequestData = netWorkService.decryptData(networkDO, text, 0);
            log.info("{}解密客户端的数据{}", MODEL, decRequestData);
            // 响应客户端
            String responseMsg = MODEL + "服务端响应信息：" + System.currentTimeMillis();
            // 加密响应信息
            HttpResponseVO<Object> httpResponseVO = netWorkService.encryptedData(networkDO, responseMsg, 1);
            context.channel().writeAndFlush(new TextWebSocketFrame(JSON.toJSONString(httpResponseVO)));
//            String receivedMsg = httpResponseVO.getData().toString();
//            HttpResponseVO<Object> decHttpResponseVO = netWorkService.decryptData(networkDO, receivedMsg, 1);
//            log.info("待解密密文：{}", receivedMsg);
//            log.info("自我解密：{}", decHttpResponseVO);
        } else {
            // 不接受文本以外的数据帧类型
            context.channel().writeAndFlush(WebSocketCloseStatus.INVALID_MESSAGE_TYPE).addListener(ChannelFutureListener.CLOSE);
        }
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        super.channelInactive(ctx);
        log.info("{}通信链接断开：{}", MODEL, ctx.channel().remoteAddress());
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        super.channelActive(ctx);
        log.info("{}通信链接创建：{}", MODEL, ctx.channel().remoteAddress());
    }
}
